package cn.hc.sp06.fallback;

import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import web.util.JsonResult;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author 海绵宝宝
 * date 2021/11/9 22:57
 */


/*
 * 通过zuul网关调用后台商品服务失败时，
 * 会执行这段降级代码，向客户端返回降级结果
 * Hystrix做降级的话，需要实现一个FallbackProvider这个接口
 */
@Component
public class itemFB implements FallbackProvider {
    /*
    设置当前降级类，是针对哪个服务的降级类
    - item-service：只针对商品服务降级
    调用用户或者订单服务失败，是不执行降级的
    - *:针对所有服务都应用当前降级类
    - null，他和*相同作用
     */
    @Override
    public String getRoute() {
        return "item-service";
    }

    /**
     * 降级的返回结果
     * 发送给客户端的降级结果。
     * 要封装在Response对象中
     */

    /*
    这个方法返回的就是一个Response响应对象
    这里面包含的就是返回给客户端的响应结果
    那这个响应结果，如果做降级处理的话，降级的结果可以是简单的错误提示
    比如”服务不可用“等等
     */
    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        //把降级结果封装在新创建的这个Response对象中
        //数据就在这些接口实现中进行设置
        return new ClientHttpResponse() {
            //StatusCode是一个封装对象
            //比如状态码200,状态文本"OK"
            //封装了这两个值
            //返回的是HTTP协议的状态
            @Override
            public HttpStatus getStatusCode() throws IOException {
                //返回一个500错{code:500,text:"服务内部错"}
                return HttpStatus.INTERNAL_SERVER_ERROR;
            }

            //RawStatusCode返回的是一个int类型的整数
            //他返回的是200的值
            //单独拿出来，进行返回200
            @Override
            public int getRawStatusCode() throws IOException {
                //value（）单独把500拿出来返回
                return HttpStatus.INTERNAL_SERVER_ERROR.value();
            }

            //状态文本
            //返回OK这个字符串文本
            @Override
            public String getStatusText() throws IOException {
                //把”服务内部错“文本返回回去
                return HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase();
            }

            //这个是用来关闭流的，咱们这是用不到的
            @Override
            public void close() {
                //ByteArrayInputStream这个流根本不需要关闭。所以用不到
            }

            //协议体
            @Override
            public InputStream getBody() throws IOException {
                //JsonResult {code:500,msg:"调用商品服务失败",data:null}
                String json = JsonResult.err().code(500).msg("调用商品服务失败！").toString();
                return new ByteArrayInputStream(json.getBytes("UTF-8"));
            }

            //协议头
            @Override
            public HttpHeaders getHeaders() {
                //返回给客户端的协议头属性
                //Content-Type:application/json;charset=UTF-8
                HttpHeaders h=new HttpHeaders();
                h.add("Content-Type","application/json;charset=UTF-8");
                return h;
            }
        };
    }
}
